DATE = "wait..."
WEEK = ".."
---@type table<string, number>
TIMES = {
  HH = 0,
  MM = 0,
  SS = 0
}
---@class timeApi
---@field x number
---@field y number
---@field RESPONSE table<string, string>
local timeApi = {
  x = 0,
  y = 0,
  RESPONSE = nil
}

function Split(szFullString, szSeparator)
  local nFindStartIndex = 1
  local nSplitIndex = 1
  local nSplitArray = {}
  while true do
    local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
    if not nFindLastIndex then
      nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
      break
    end
    nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
    nFindStartIndex = nFindLastIndex + string.len(szSeparator)
    nSplitIndex = nSplitIndex + 1
  end
  return nSplitArray
end

local function get_days_in_month(month, year)
  local function is_leap_year(year)
    return year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0)
  end
  return month == 2 and is_leap_year(year) and 29
          or ("\31\28\31\30\31\30\31\31\30\31\30\31"):byte(month)
end

local function get_day_of_week(yy, mm, dd)
  local days = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }
  local mmx = mm
  if (mm == 1) then  mmx = 13; yy = yy-1  end
  if (mm == 2) then  mmx = 14; yy = yy-1  end
  local val8 = dd + (mmx*2) +  math.floor(((mmx+1)*3)/5)   + yy + math.floor(yy/4)  - math.floor(yy/100)  + math.floor(yy/400) + 2
  local val9 = math.floor(val8/7)
  local dw = val8-(val9*7)
  if (dw == 0) then
    dw = 7
  end
  return (dw+6)%8+1, days[dw]
end

local function getTimeRequest(callback)
  http.get("http://quan.suning.com/getSysTime.do", 'Content-Type: text/html; charset=UTF-8',
          function(code, data)
            if code == 200 then
              --print(code, data)
              -- data : {"sysTime2":"2021-06-29 17:14:37","sysTime1":"20210629171437"}
              timeApi.RESPONSE = sjson.decode(data)
              DATE = Split(timeApi.RESPONSE.sysTime2, " ")
              local times = Split(DATE[2], ":")
              -- get time
              TIMES.HH = times[1]
              TIMES.MM = times[2]
              TIMES.SS = times[3]
              -- get date
              DATE = DATE[1]
              -- get week
              data = Split(DATE, "-")
              local yy, mm, dd = data[1], data[2], data[3]
              _, WEEK = get_day_of_week(yy, mm, dd)
              -- show
--              timeApi.show(timeApi)
              callback ()
            end
          end)
end

function timeApi:update(callback)
  getTimeRequest(callback)
end

function timeApi:countTime()
  if not self.RESPONSE then return end
  TIMES.SS = TIMES.SS + 1
  -- MM + 1
  if TIMES.SS >= 60 then
    TIMES.MM = TIMES.MM + 1
    TIMES.SS = 0
    -- HH + 1
    if TIMES.MM >= 60 then
      TIMES.HH = TIMES.HH + 1
      TIMES.MM = 0
      -- DD
      if TIMES.HH >= 24 then
        TIMES.HH = 0
        local date = Split(DATE, "-")
        local yy, mm, dd = date[1],  date[2], date[3]
        -- Month + 1
        dd = dd + 1
        if get_days_in_month(mm, yy) < dd then
          mm = mm + 1
          dd = 1
          -- year + 1
          if mm > 12 then
            yy = yy + 1
            mm = 1
          end
        end
        DATE = yy.."-"..mm.."-"..dd
        _, WEEK = get_day_of_week(yy, mm, dd)
      end
    end
  end
end

---@param x number
---@param y number
function timeApi:show()
  self.x = tonumber(self.x) or self.x
  self.y = tonumber(self.y) or self.y
  self:countTime()
  disp:clearBuffer()
  disp:drawFrame(self.x + 0, self.y + 0,128,64)
  disp:setFont(u8g2.font_unifont_t_symbols)
  disp:drawStr(self.x + 10, self.y + 1, DATE)
  disp:drawStr(self.x + 100, self.y + 20, WEEK)
  disp:setFont(u8g2.font_fub25_tn)
  disp:drawStr(self.x + 10, self.y + 20, string.format("%.2d:%.2d", TIMES.HH or 0, TIMES.MM or 0))
  disp:setFont(u8g2.font_unifont_t_symbols)
  disp:drawStr(self.x + 100, self.y + 32, string.format("%.2d", TIMES.SS or 0))
  --  disp:drawStr(50, 40, "你好:uso")
  --  disp:drawFrame(0, 16,128,45)
  disp:sendBuffer()
end

--- @return string
function timeApi:getResp()
  return self.RESPONSE and self.RESPONSE.sysTime2
end

return timeApi
